package com.tc.banana.framework.servlet;

import java.io.IOException;
import java.util.Enumeration;
import java.util.Map.Entry;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.tc.banana.framework.ConfigHelper;
import com.tc.banana.framework.HelperLoader;
import com.tc.banana.framework.ServletHelper;
import com.tc.banana.framework.enums.RequestMethod;
import com.tc.banana.framework.exception.ServletMethodException;
import com.tc.banana.framework.servlet.model.ModelAndView;
import com.tc.banana.framework.servlet.model.Param;
import com.tc.banana.framework.servlet.model.ServletHandle;
import com.tc.banana.framework.util.ReflectionUtil;
import com.tc.banana.framework.util.StringUtil;

/** 
 * @author  wdd 
 * @date 创建时间：2016年4月3日 下午9:00:24 
 */
public class DispatcherServlet extends HttpServlet{
	
	private static final long serialVersionUID = 1L;

	@Override
	public void init(ServletConfig config) throws ServletException {
		HelperLoader.init();
	}
	
	@Override
	public void service(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		String requestURI = request.getRequestURI();
		request.getRequestURL();
		requestURI = requestURI.substring(requestURI.lastIndexOf("/"), requestURI.indexOf("."));
		String method = request.getMethod();
		if (ServletHelper.isMatched(requestURI)) {
			ServletHandle handle = ServletHelper.getMatchedHandler(requestURI);
			RequestMethod acMethod = handle.getRequestMethod();
			// 判断请求方法是否正确
			if (acMethod.getName().equalsIgnoreCase(method)) {
				// 参数赋值
				Param param = initParam(request, requestURI, acMethod);
				// 执行方法
				Object result = ReflectionUtil.invokeMethod(handle.getObject(), handle.getMethod(), param);
//				request.getRequestDispatcher("/WEB-INF/view/" + (String) result).forward(request, response);
				if (result instanceof String) {
					request.getRequestDispatcher(appendUriMapper(request, (String) result)).forward(request, response);
				} else if (result instanceof ModelAndView){
					ModelAndView view = (ModelAndView) result;
					Param pr = view.getParam();
					for (Entry<String, Object> e : pr.entrySet()) {
						request.setAttribute(e.getKey(), e.getValue());
					}
					request.getRequestDispatcher(appendUriMapper(request, view.getViewName())).forward(request, response);
				}
			} else 
				throw new ServletMethodException("the request method not matched, cannot find method " + method);
			
		}
	}

	public Param initParam(HttpServletRequest request, String requestURI, RequestMethod acMethod) {
		Param param = new Param();
		if (acMethod == RequestMethod.POST) {
			Enumeration<String> parameterNames = request.getParameterNames();
			while (parameterNames.hasMoreElements()) {
				String paramName = parameterNames.nextElement();
				String value = request.getParameter(paramName);
				param.put(paramName, value);
			}
		} else if (acMethod == RequestMethod.GET) {
			if (requestURI.lastIndexOf("?") != -1 ){
				String getParam = requestURI.substring(requestURI.lastIndexOf("?"));
				if (StringUtil.isNotBlank(getParam)) {
					String [] expressions = getParam.split("&");
					for (String expression : expressions) {
						String arg[] = expression.split("=");
						param.put(arg [0], arg [1]);
					}
				}
			}
		}
		return param;
	}
	
	public String appendUriMapper (HttpServletRequest request, String uri) {
		return new StringBuilder(ConfigHelper.getAppJspPath()).append(uri).append(".jsp").toString();
	}
}
